using System;
using Servlets.Utils;

namespace Servlets.Api
{
	/// <summary>
	/// Cookie is an immutable class that represents the Cookie used in the HTTP protocol
	/// </summary>
	public class Cookie
	{
		private string _name;
		public string Name{get{return _name.UrlDecode();} private set{_name = value.UrlEncode();}}
		
		private string _value;
		public string Value{get{return _value.UrlDecode();} private set{_value = value.UrlEncode();}}
		
		
		public string Path{get;private set;}
		public string Domain{get;private set;}
		public DateTime ExpirationDate{get;private set;}
		private bool reconstructed;
		
		public Cookie (string key, string value) : this(key, value, "/", "", DateTime.Now.AddDays(1)){}
		public Cookie (string key, string value, DateTime expirationDate) : this(key, value, "/", "", expirationDate){}
		public Cookie(string key, string value, string path, string domain, DateTime expirationDate) {
			this.Name = key;
			this.Value = value;
			this.Path = path;
			this.Domain = domain;
			this.ExpirationDate = expirationDate;
			Console.WriteLine ("Blah");
		}
		
		/// <summary>
		/// Creates a cookie with a name and value.
		/// </summary>
		/// <param name="key">
		/// A <see cref="System.String"/>
		/// </param>
		/// <param name="value">
		/// A <see cref="System.String"/>
		/// </param>
		/// <param name="reconstructing">
		/// A <see cref="System.Boolean"/> saying if the cookie was sent in the request. This flag is set because browsers don't send the expiration date.
		/// </param>
		public Cookie(string key, string value, bool reconstructing) {
			this.Name = key;
			this.Value = value;
			this.reconstructed = reconstructing;
		}
		
		/// <summary>
		/// Returns the Cookie as a string. The string is formatted according to the HTTP standard for cookies.
		/// </summary>
		/// <returns>
		/// A <see cref="System.String"/>
		/// </returns>
		public override string ToString ()
		{
			if(reconstructed) {
				return String.Format("{0}={1}", Name, Value);
			}

			string date = ExpirationDate.ToUniversalTime().ToString();
			string cookie = string.Format ("{0}={1}; expires={2}; path={3}", Name, Value, date, Path);
			if(Domain != "") {
				cookie += "; " +Domain;
			}
			return cookie;
		}
		
		public override bool Equals (object obj)
		{
			Cookie c = obj as Cookie;
			if(c == null) {
				return false;
			}
			if(c.Name != this.Name) {
				return false;
			}
			if(c.Value != this.Value) {
				return false;
			}
			if(c.Domain != this.Domain) {
				return false;
			}
			if(c.Path != this.Path) {
				return false;
			}
			return true;
		}
		
		
		/// <summary>
		/// Returns a cookie that cause this cookie to be deleted if set in the response
		/// </summary>
		/// <returns>
		/// A <see cref="Cookie"/>
		/// </returns>
		public Cookie Delete() {
			return new Cookie(this.Name, this.Value, this.Path, this.Domain, DateTime.MinValue);
		}
		
		public override int GetHashCode ()
		{
			return Name.GetHashCode() ^ Value.GetHashCode();
		}
	}
}